﻿#include "mainholdwidget.h"
#include<QMessageBox>
#include<qdebug.h>
#include"CtpInterface/ctpinterface.h"

extern CTPInterface* g_CTPInterface;

InvestorPosition::InvestorPosition(QString futu_code,char entrust_bs,int begin_amount,int enable_amount,int real_enable_amount,int real_current_amount,int old_current_amount):
  m_futu_code(futu_code),
  m_entrust_bs(entrust_bs),
  m_begin_amount(begin_amount),
  m_enable_amount(enable_amount),
  m_real_enable_amount(real_enable_amount),
  m_real_current_amount(real_current_amount),
  m_old_current_amount(old_current_amount){

}

MainHoldWidget::MainHoldWidget(QWidget *parent) :
    QWidget(parent)
{
//    m_InstrumentMarginRateFutucode = 0;
//    m_ContractInfo                 = 0;

    setupModel();
    setupViews();

    connect(m_tableHold,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(TableDoubleClicked(QModelIndex)));
}

void MainHoldWidget::setupModel()
{
    m_modelHold = new QStandardItemModel(0, 12, this);
    m_modelHold->setHeaderData(0, Qt::Horizontal, QStringLiteral("合约代码"));
    m_modelHold->setHeaderData(1, Qt::Horizontal, QStringLiteral("买卖"));
    m_modelHold->setHeaderData(2, Qt::Horizontal, QStringLiteral("今开可用"));
    m_modelHold->setHeaderData(3, Qt::Horizontal, QStringLiteral("历史开可用"));
    m_modelHold->setHeaderData(4, Qt::Horizontal, QStringLiteral("总可用"));
    m_modelHold->setHeaderData(5, Qt::Horizontal, QStringLiteral("总持仓"));
    m_modelHold->setHeaderData(6, Qt::Horizontal, QStringLiteral("开仓均价"));
    m_modelHold->setHeaderData(7, Qt::Horizontal, QStringLiteral("履约保证金"));
    m_modelHold->setHeaderData(8, Qt::Horizontal, QStringLiteral("浮动盈亏"));
    m_modelHold->setHeaderData(9, Qt::Horizontal, QStringLiteral("盯市盈亏"));
    m_modelHold->setHeaderData(10, Qt::Horizontal, QStringLiteral("投机套保"));
	m_modelHold->setHeaderData(11, Qt::Horizontal, QStringLiteral("交易市场"));
}

bool MainHoldWidget::eventFilter(QObject *obj, QEvent *event){
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent* keyEvent = (QKeyEvent*)(event);
        emit SigkeyPressEvent(keyEvent);
        return true;
    } else {
        // standard event processing
        return QObject::eventFilter(obj, event);
    }
}
/*bool MainHoldWidget::GetInstrumentMarginRateFutucodeFlg(){
    if(m_InstrumentMarginRateFutucode == 0){
        return false;
    }else{
        m_Mutex.lock();
        m_InstrumentMarginRateFutucode--;
        m_Mutex.unlock();
        return true;
    }
}
bool MainHoldWidget::GetContractInfoFlg(){
    if(m_ContractInfo == 0){
        return false;
    }else{
        m_Mutex.lock();
        m_ContractInfo--;
        m_Mutex.unlock();
        return true;
    }
}*/

//获取今日开仓可用数量
int MainHoldWidget::GetRealEnableAmount(QString futucode,char entrust_bs){
    switch(entrust_bs){
    case '1'://多头
        return m_LongPositions[futucode]->GetRealEnableAmount();
        break;
    case '2'://空头
        return m_ShortPositions[futucode]->GetRealEnableAmount();
        break;
    default:
        break;
    }
    return 0;
}

void MainHoldWidget::AddRow(CThostFtdcInvestorPositionField *pInvestorPosition,int amountPerHand){
	
    QString futures_account = QString(pInvestorPosition->InvestorID);
    QString futu_code       = QString(pInvestorPosition->InstrumentID);
	if(futures_account == "" || futu_code == ""){
		return;
	}
	m_UpdateMutex.lock();

    //保存合约的每手数量
    if(!m_MapAmountPerHand.contains(futu_code)){
        m_MapAmountPerHand.insert(futu_code,amountPerHand);
    }

    char entrust_bs = pInvestorPosition->PosiDirection;	//买卖方向
    int begin_amount = pInvestorPosition->YdPosition;//期初数量
    int enable_amount = pInvestorPosition->Position ;//可用数量
    int real_enable_amount = pInvestorPosition->TodayPosition;//当日开仓可用数量
    int real_current_amount = pInvestorPosition->TodayPosition;//今总持仓
    int old_current_amount = pInvestorPosition->Position - pInvestorPosition->TodayPosition;//老仓持仓数量

    InvestorPosition* pos = new InvestorPosition(futu_code,entrust_bs,begin_amount,enable_amount,real_enable_amount,real_current_amount,old_current_amount);

    m_modelHold->insertRow(0);

    ///合约代码
    ((QStandardItemModel*) m_modelHold)->setItem(0, 0, new QStandardItem(futu_code));
    ///持仓多空方向
    switch(entrust_bs){
    case THOST_FTDC_PD_Net:///净
        ((QStandardItemModel*) m_modelHold)->setItem(0, 1, new QStandardItem(QStringLiteral("净")));
        break;
    case THOST_FTDC_PD_Long:///多头
        m_LongPositions.insert(futu_code,pos);
        ((QStandardItemModel*) m_modelHold)->setItem(0, 1, new QStandardItem(QStringLiteral("多头")));
        break;
    case THOST_FTDC_PD_Short:///空头
        m_ShortPositions.insert(futu_code,pos);
        ((QStandardItemModel*) m_modelHold)->setItem(0, 1, new QStandardItem(QStringLiteral("空头")));
        break;
    default:
        break;
    }

    ((QStandardItemModel*) m_modelHold)->setItem(0, 2, new QStandardItem(QString::number(real_enable_amount)));//今开可用
    ((QStandardItemModel*) m_modelHold)->setItem(0, 3, new QStandardItem(QString::number(old_current_amount)));//历史开可用
    ((QStandardItemModel*) m_modelHold)->setItem(0, 4, new QStandardItem(QString::number(enable_amount)));//总可用
    ((QStandardItemModel*) m_modelHold)->setItem(0, 5, new QStandardItem(QString::number(enable_amount)));//总持仓
    //开仓均价
    double openavg = 0;
	if(amountPerHand != 0 && pInvestorPosition->Position != 0){
        openavg = pInvestorPosition->PositionCost/amountPerHand/pInvestorPosition->Position;
	}    
    ((QStandardItemModel*) m_modelHold)->setItem(0, 6, new QStandardItem(QString("%1").arg(openavg, 0, 'f', 3)));
    //履约保证金
    ((QStandardItemModel*) m_modelHold)->setItem(0, 7, new QStandardItem(QString("%1").arg(pInvestorPosition->UseMargin, 0, 'f', 3) ));
    //浮动盈亏
    ((QStandardItemModel*) m_modelHold)->setItem(0, 8, new QStandardItem(QString("%1").arg(pInvestorPosition->PositionProfit, 0, 'f', 3)));
    //盯市盈亏
    //double CloseProfitByDate = (openavg - pInvestorPosition->PreSettlementPrice) * pInvestorPosition->Position;
    //((QStandardItemModel*) m_modelHold)->setItem(0, 9, new QStandardItem(QString("%1").arg(CloseProfitByDate, 0, 'f', 3) ));
	((QStandardItemModel*) m_modelHold)->setItem(0, 9, new QStandardItem(QString("-")));

    ///投机套保标志
    char hedge_type = pInvestorPosition->HedgeFlag;
    switch(hedge_type){
    case THOST_FTDC_HF_Speculation:///投机
        ((QStandardItemModel*) m_modelHold)->setItem(0, 10, new QStandardItem(QStringLiteral("投机")));
        break;
    case THOST_FTDC_HF_Hedge:///套保
        ((QStandardItemModel*) m_modelHold)->setItem(0, 10, new QStandardItem(QStringLiteral("套保")));
        break;
    case THOST_FTDC_HF_Arbitrage:///套利
		((QStandardItemModel*) m_modelHold)->setItem(0, 10, new QStandardItem(QStringLiteral("套利")));
		break;
    default:
        break;
    }
    ((QStandardItemModel*) m_modelHold)->setItem(0, 11, new QStandardItem(QString("-")));

    ///订阅行情
    QStringList lst;
    lst<<futu_code;
    g_CTPInterface->SubscribeMarketData(lst);

	m_UpdateMutex.unlock();
}

void MainHoldWidget::setupViews()
{
    hboxlayout = new QHBoxLayout;
    QLabel* accountLabel = new QLabel(QStringLiteral("资金账号"));
    m_accountCombox = new QComboBox;
    m_querybutton = new QPushButton(QStringLiteral("查询"));
    m_exportbutton = new QPushButton(QStringLiteral("导出"));

    accountLabel->setFixedWidth(80);
    m_accountCombox->setFixedWidth(100);
    m_querybutton->setFixedWidth(80);
    m_exportbutton->setFixedWidth(80);

    hboxlayout->addWidget(accountLabel);
    hboxlayout->addWidget(m_accountCombox);
    hboxlayout->addWidget(m_querybutton);
    hboxlayout->addWidget(m_exportbutton);
    hboxlayout->addStretch();
    hboxlayout->addStretch();

    MainLayout = new QGridLayout(this);

    m_tableHold = new QTableView;
    m_tableHold->setAlternatingRowColors(true);
    QFont font = m_tableHold->horizontalHeader()->font();
    font.setBold(true);
    m_tableHold->horizontalHeader()->setFont(font);

    m_tableHold->setModel(m_modelHold);
    m_tableHold->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_tableHold->verticalHeader()->setVisible(false); //隐藏列表头
    m_tableHold->verticalHeader()->setFixedWidth(20);
    m_tableHold->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_tableHold->setSelectionMode(QAbstractItemView::SingleSelection);

    m_tableHold->setColumnWidth(0, 100);
    m_tableHold->setColumnWidth(1, 100);
    m_tableHold->setColumnWidth(2, 100);
    m_tableHold->setColumnWidth(3, 120);
    m_tableHold->setColumnWidth(4, 100);
    m_tableHold->setColumnWidth(5, 100);
    m_tableHold->setColumnWidth(6, 100);
    m_tableHold->setColumnWidth(7, 100);
    m_tableHold->setColumnWidth(8, 100);
    m_tableHold->setColumnWidth(9, 100);
    m_tableHold->setColumnWidth(10, 100);
    m_tableHold->setColumnWidth(11, 100);
    m_tableHold->setColumnWidth(12, 100);

    MainLayout->addLayout(hboxlayout,0,0);
    MainLayout->addWidget(m_tableHold,1,0);
    MainLayout->setMargin(0);
    MainLayout->setSpacing(0);

	//创建菜单、菜单项
	this->m_tableHold->setContextMenuPolicy(Qt::CustomContextMenu);
	m_RightPopMenu = new QMenu(this->m_tableHold);
	m_ShijiaAction = new QAction(QStringLiteral("市价平仓"),this); 
	m_DuijiaAction = new QAction(QStringLiteral("对价平仓"),this); 
	m_updateAction = new QAction(QStringLiteral("刷新"),this);
	m_outputAction = new QAction(QStringLiteral("导出"),this); 
	m_RightPopMenu->addAction(m_ShijiaAction);
	m_RightPopMenu->addAction(m_DuijiaAction);
	m_RightPopMenu->addAction(m_updateAction);
	m_RightPopMenu->addAction(m_outputAction);
    //右键弹出菜单事件绑定
	connect(this->m_tableHold,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(RightClickedMenuPop(const QPoint&)));
	//查询按钮事件绑定
    connect(this->m_querybutton,SIGNAL(clicked()),this,SLOT(QueryButtonClicked()));
	//市价平仓事件绑定
	connect(m_ShijiaAction, SIGNAL(triggered()), this, SLOT(ShijiaAction()));
	//对价平仓事件绑定
	connect(m_DuijiaAction, SIGNAL(triggered()), this, SLOT(DuijiaAction()));
	//刷新事件绑定
	connect(m_updateAction, SIGNAL(triggered()), this, SLOT(UpdateHold()));
	//导出事件绑定
	connect(m_outputAction, SIGNAL(triggered()), this, SLOT(OutputHold()));

    m_tableHold->installEventFilter(this);
}
//市价平仓事件绑定
void MainHoldWidget::ShijiaAction(){

}
//对价平仓事件绑定
void MainHoldWidget::DuijiaAction(){

}
//刷新事件绑定
void MainHoldWidget::UpdateHold(){
	this->QueryButtonClicked();
}
//当收到成交回报时 更新用户的持仓信息
void MainHoldWidget::UpdateHold(CThostFtdcTradeField *pTrade){
    /*QString code = pTrade->InstrumentID;
    TThostFtdcDirectionType bs = pTrade->Direction;
    TThostFtdcOffsetFlagType offsetflg = pTrade->OffsetFlag;

    int iCnt =  m_modelHold->rowCount();
    for(int i = 0; i< iCnt; i++){
        QString codeTmp = m_modelHold->item
        if(){

        }
    }

    ///买
    #define THOST_FTDC_D_Buy '0'
    ///卖
    #define THOST_FTDC_D_Sell '1'


    ///开仓
    #define THOST_FTDC_OF_Open '0'
    ///平仓
    #define THOST_FTDC_OF_Close '1'
    ///强平
    #define THOST_FTDC_OF_ForceClose '2'
    ///平今
    #define THOST_FTDC_OF_CloseToday '3'
    ///平昨
    #define THOST_FTDC_OF_CloseYesterday '4'
    ///强减
    #define THOST_FTDC_OF_ForceOff '5'
    ///本地强平
    #define THOST_FTDC_OF_LocalForceClose '6'*/

}
//导出事件绑定
void MainHoldWidget::OutputHold(){

}

///右键弹出菜单响应函数
void MainHoldWidget::RightClickedMenuPop(const QPoint& pos)
{
    //m_RightPopMenu->exec(QCursor::pos());
}
///双击平仓
void MainHoldWidget::TableDoubleClicked(const QModelIndex &index){
    int iRow = index.row();

    QString exch_type    = index.sibling(iRow,11).data().toString();
    QString contractcode = index.sibling(iRow,0).data().toString();
    QString bs           = index.sibling(iRow,1).data().toString();
    int     real_enable_amount = index.sibling(iRow,2).data().toInt();
    int     enable_amount      = index.sibling(iRow,4).data().toInt();
    char c_bs;
    char c_direction = '2';//平仓
    char c_hedge = '0';//投机
    if(bs == QStringLiteral("多头")){
        c_bs = THOST_FTDC_D_Sell;//卖
    }else{
        c_bs = THOST_FTDC_D_Buy;//买
    }

    emit SigClosePositon(exch_type,contractcode,c_bs,c_direction,c_hedge, real_enable_amount,enable_amount);
}
//根据行情信息更新持仓损益
void MainHoldWidget::UpdateByDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData){
	m_UpdateMutex.lock();
    QString futucode = pDepthMarketData->InstrumentID;
    if(!m_LongPositions.contains(futucode) && !m_ShortPositions.contains(futucode)){
        return;
    }

    int iCnt =  m_modelHold->rowCount();
    for(int i = 0; i< iCnt; i++){
        QString codeTmp = ((QStandardItemModel*)m_modelHold)->item(i,0)->text();
        if(codeTmp != futucode){
            continue;
        }
        if(m_MapAmountPerHand.contains(futucode)){
            int    cnt     = ((QStandardItemModel*)m_modelHold)->item(i,4)->text().toInt();  //持仓手数
            double openavg = ((QStandardItemModel*)m_modelHold)->item(i,6)->text().toDouble();//开仓均价
            QString bs     = ((QStandardItemModel*)m_modelHold)->item(i,1)->text();
            double PositionProfit = 0;
            if(bs == QStringLiteral("多头")){
                PositionProfit = (pDepthMarketData->LastPrice - openavg)*cnt*m_MapAmountPerHand[futucode];
            }else if(bs == QStringLiteral("空头")){
                PositionProfit = (openavg - pDepthMarketData->LastPrice )*cnt*m_MapAmountPerHand[futucode];
            }
            //浮动盈亏
            ((QStandardItemModel*) m_modelHold)->setItem(i, 8, new QStandardItem(QString("%1").arg(PositionProfit, 0, 'f', 3)));
        }
    }
	m_UpdateMutex.unlock();
}

void MainHoldWidget::QueryButtonClicked(){
	m_UpdateMutex.lock();
    for (QMap<QString,InvestorPosition*>::iterator it = m_ShortPositions.begin();it != m_ShortPositions.end(); ++it ) {
            delete it.value();
    }
    for (QMap<QString,InvestorPosition*>::iterator it = m_LongPositions.begin();it != m_LongPositions.end(); ++it ) {
            delete it.value();
    }
    m_ShortPositions.clear();
    m_LongPositions.clear();

    m_modelHold->removeRows(0,m_modelHold->rowCount());
    //查询持仓
    g_CTPInterface->ReqQryInvestorPosition();
	m_UpdateMutex.unlock();
}
